/* codeml_leo.cpp
*/
#include "codeml_results.h"
#include <cstdio>
#include <string>
#include <stdexcept>
#include <algorithm>


namespace
{
//
// should not be first field, i.e. should always be preceded by tab
//
struct read_tab_newline_delimited_str
{
	std::string& str;
	read_tab_newline_delimited_str(std::string& str_):str(str_){}
};
std::istream& operator >> (std::istream& istrm, read_tab_newline_delimited_str result)
{
	// ignore first tab
	// leave trailing whitespace


	// ignore first tab
	char tabchar = istrm.get();
	if (tabchar != '\t')
		throw std::runtime_error("String in invalid format.");
	result.str.clear();
	char c;
	while ((c = istrm.peek()) != EOF)
	{
		if (c == '\t' || c == '\n')
			break;
		result.str += istrm.get();
	}
	return istrm;
}

}



std::istream& operator >> (std::istream& istrm, t_codeml_results& res)
{
	if (!istrm)
		return istrm;
	istrm		>>	res.dN
				>>	res.dS
				>>	res.dN_dS
				>>	res.N
				>>	res.S
				>>	res.std_err_dN
				>>	res.std_err_dS
				>>	res.kappa
				>>	res.lnL
				>>	res.dT
				>>	read_tab_newline_delimited_str(res.error_str);
	return istrm;
}


std::ostream& operator <<(std::ostream& strm, const t_codeml_results& res)
{
	std::string output_error_str = res.error_str;
	std::replace(output_error_str.begin(), output_error_str.end(), '\n', ' ');
	std::replace(output_error_str.begin(), output_error_str.end(), '\t', ' ');
	strm	<<	res.dN			<< '\t'
			<<	res.dS			<< '\t'
			<<	res.dN_dS		<< '\t'
			<<	res.N			<< '\t'
			<<	res.S			<< '\t'
			<<	res.std_err_dN	<< '\t'
			<<	res.std_err_dS	<< '\t'
			<<	res.kappa		<< '\t'
			<<	res.lnL			<< '\t'
			<<	res.dT			<< '\t'
			<<	output_error_str;
	return strm;
}


std::string t_codeml_results::comma_delimited_fields()
{
	return "ka,ks,kaks,count_a,count_s,ka_stderr,ks_stderr,kappa,lnL,t,error_str";
}

std::string t_codeml_results::column_names()
{
	return
			"dN\t"
			"dS\t"
			"dN/dS\t"
			"N\t"
			"S\t"
			"dN_std_err\t"
			"dS_std_err\t"
			"kappa\t"
			"lnL\t"
			"tau\t"
			"error_str";

}

std::string t_codeml_results::column_name_underscores()
{
	return
			"--\t"
			"--\t"
			"-----\t"
			"-\t"
			"-\t"
			"----------\t"
			"----------\t"
			"-----\t"
			"---\t"
			"---\t"
			"---------";
}

